From Reflex to Planning
In the evolution of agent design, we move from Reflex Agents, which map percepts directly to actions based on simple rules (e.g., “If car in front brakes, initiate braking”), to Problem-Solving Agents. Reflex agents operate on immediate context, whereas problem-solving agents are Goal-based. They consider the future consequences of their actions to find a sequence that satisfies a specific objective.
- Reflex Agent: $Action = Function(Percept)$
- Planning Agent: $Action\_Sequence = Search(State, Goal)$
The Atomic State Representation
At this fundamental level, agents utilize an Atomic Representation. This means the state of the world is treated as a black box—a singular node with no internal structure visible to the search algorithm. The agent reasons only about:
- States ($S$): Snapshots of the environment.
- Actions ($A$): Transitions between states.
- Goal Test: A boolean check if state $s \in S_{goal}$.
The Problem-Solving Loop
A problem-solving agent follows a distinct four-step cycle to navigate the environment:
- Goal Formulation: Deciding which objective to pursue based on current situation.
- Problem Formulation: Abstracting the real world into a mathematical model (States and Actions).
- Search: Simulating sequences of actions to find the optimal path.
- Execution: Performing the actions found during the search phase without further deliberation (assuming a static environment).
Python Implementation (agent_types.py)
1
class ReflexAgent:
2
def act(self, percept):
3
# Direct mapping: Rule -> Action
4
return rules.get(percept, default_action)
5
6
class ProblemSolvingAgent:
7
def __init__(self):
8
self.seq = [] # Buffered action sequence
9
10
def act(self, percept):
11
# If we are mid-execution, continue
12
if self.seq:
13
return self.seq.pop(0)
14
15
# Otherwise, Plan (Search)
16
state = self.update_state(percept)
17
goal = self.formulate_goal(state)
18
problem = self.formulate_problem(state, goal)
19
20
# Search returns a list of actions
21
self.seq = search_algorithm(problem)
22
23
return self.seq.pop(0)